import os.path
from typing import Callable, Union, List, Any, Tuple


class Downloader(object):
    _CREATORS: List[Callable[[str, str, str], Any]] = []

    def __init__(self, name: str, url: str):
        self._name = name
        self._url = url
        self._last_error = ''

    @staticmethod
    def create(url: str, output_dir: str, filename: Union[None, str] = None):
        for creator in Downloader._CREATORS:
            parser = creator(url, output_dir, filename)
            if parser:
                return parser
        return None

    @staticmethod
    def register_creator(creator: Callable[[str, str, str], Any]):
        Downloader._CREATORS.append(creator)

    def name(self) -> str:
        return self._name

    def url(self) -> str:
        return self._url

    def last_error(self) -> str:
        return self._last_error

    def _set_last_error(self, error: str):
        self._last_error = error

    def download(self, on_progress: Union[None, Callable[[int, int], None]] = None)\
            -> Tuple[bool, Union[None, str], Union[None, str]]:
        # implement by child
        pass
